/*
 * class name: menu$,
 * copyright: maximus zhang,
 * License: MIT-LICENSE,
 * contact: maximus.zhang@gmail.com,
 * required-js: http://hcjs.googlecode.com/svn/trunk/hc.js,
 * update: http://hcjs.googlecode.com/svn/trunk/menu.js
 *
 */
function menu$(){
    var A = arguments,
        _ = this;
    _ = ext$( _, ext$( {
        id : 'menu'+ now$(3),
        elem : me.body,
        cssname : '',
        menu : [
            /* each item has the following properties
                split can only have txt==='-|-' property
            */
            {
            id : '',
            cls : '',
            css : '',
            a : { id : '_'+ now$(3), href : '', cls : '', css : ''},
            ico : {src:'', alt:''},
            label : {txt:'-|-', css:''},
            key : '',
            menu : [],
            fn : function(){;}
            }
        ],
        arr : {right: '/icos/arr1right.gif', down: '/icos/arr1down.gif'}
        }, A[0] ) );

    _.uitype = 'menu$';

    _.active = false;
    _.over = false;
    _.bound = false;
    _.menus = {};
}

menu$.prototype = {
    hide$ : function(){
        if ( !this.active||this.over ) {
            return false;
        }

        /* hide all menuitems */
        for ( var n in this.menus ) {
            var mi = this.menus[n];
            if ( mi.style.display!='none' ) {
                mi.style.display = 'none';

                /* menu root */
                var pmid = mi.id.replace(/^sub_/,'');
                if ( !/^sub_/.test(pmid) ) {
                    var pm = $(pmid);
                    if ( pm.firstChild && pm.firstChild.className=='a' ) {
                        pm.firstChild.className='';
                    }
                }
            }
        }

        if ( this.bound ) {
            unbind$(me, 'mousedown', this.hide$);
            this.bound = false;
        }

        this.over = false;
        this.active = false;

    return false;
    },

    togg$: function(menuitem){
        if ( this.active && !this.over ) {
            return this.hide$();
        }

        if ( !menuitem ) {
            return this.hide$();
        }

        var mi = menuitem;

        if ( !this.active ) {
            var pz = pos$(mi);
            if ( !/^sub_/.test(mi.id) ) {/* menu root */
                mi.firstChild.className = 'a';
                var sub = this.menus['sub_'+ mi.id],
                    subw = pos$(sub).width;
                sub.style.top = pz._bottom+2 +'px';
                sub.style.left = subw>pz.right ? pz.W-subw +'px' : pz.left +'px';
                sub.style.display = 'block';
            }
            if ( !this.bound ) {
                bind$(me,'mousedown',this.hide$);
                this.bound = true;
            }
            this.active = true;
        } else if ( this.over ) {
            if ( !/^sub_/.test(mi.id) ) {/* menu root */
                this.over = false;
                return this.hide$();
            }
            if ( this.bound ) {
                unbind$(me,'mousedown',this.hide$);
                this.bound = false;
            }
            this.active = false;
        }
    return false;
    },

    addsub$ : function(so,el,y){
        if ( !so||!el ) {
            return false;
        }

        var s = so,
            _=this,
            mx = el$('div').appendTo$(el);
        mx.className = 'z';
        mx.id = el.id +'_'+ y;
        mx.onmouseover = function(){
            _.over = true;
            _.active = true;
        };
        mx.onmouseout = function(){
            _.over = false;
        };

        if ( s.txt=='-|-' ) {
            return mx;
        }

        mx.className='x';

        var a = el$('a').appendTo$(mx);
        a.href = '#';

        if ( s.ico ) {
            var ico = el$('img').appendTo$(a);
            ico.src = s.ico;
            ico.alt = '';
        } else {
            ico=el$('span').appendTo$(a);
        }

        ico.className = 'ico';

        if ( s.txt.length>0 ) {
            var t = el$('span').appendTo$(a);
            t.className = 't';
            t.innerHTML = s.txt;
        }

        if ( s.key ) {
            var k = el$('em').appendTo$(a);
            k.innerHTML = '(<kbd>'+ s.key +'<\/kbd>)';
        }

        /**
         * menu item actions definition
         */
        if ( typeof s.fn=='function' ) {
            a.onclick=function(){
                s.fn.apply(this,[]);
                _.over=false;
            return _.hide$();
            };
        } else {
            a.onclick=function(){
            return false;
            };
        }

        a.onmouseover = function(){
            _.over = true;
            _.active = true;
        };
        a.onmouseout = function(){
            _.over = false;
        };

        if ( isArray(s.menu) && s.menu.length>0 ) {
            var m = el$('span').appendTo$(a);
            m.className = 'm';
            var ma = el$('img').appendTo$(m);
            ma.src = this.arr.right || '';
            ma.alt = '';//'►';

            /* add sub menu */
            this.sub$(s.menu,mx,true);

            /* disable menu item action */
            a.onclick = function(){
                return false;
            };
            a.onmouseover = function(){
                _.over = true;
                _.active = true;
                /* _.togg$(this);show sub menu's sub menu */
            };
            a.onmouseout = function(){
                _.over = false;
            };
            /* _.menus[mx.id] = mx; */
        }

    return mx;
    },

    sub$: function(m,pm,SUB){
        if ( !m || !pm ) {
            return false;
        }

        var sub = el$('div').appendTo$(),
            pz = pos$(pm);
        sub.style.cssText = 'display:none;';
        sub.className = 'dm';
        sub.style.top = (SUB ? pz.top : pz._bottom+2) +'px';

        var subw = pos$(sub).width;

        if ( subw>pz.right ) {
            sub.style.left=(SUB?pz.left-subw+2:pz.W-subw) +'px';
        } else {
            sub.style.left=(SUB?pz._right:pz.left) +'px';
        }

        sub.id = 'sub_'+ (pm.id ? pm.id : now$(3));
        for (var x=0,L=m.length; x<L; x++) {
            void this.addsub$(m[x],sub,x);
        }
        this.menus[sub.id] = sub;
        sub.onmouseover = function(){
            _.over = true;
        };
        sub.onmouseout = function(){
            _.over = false;
        };
    return sub;
    },

    add$: function(mo,el){
    /* parameter:({menu item obj},elem)
    generate menu item like:
    <li class='r'><a href='#' onclick='...'><img class='ico' /><span>label...</span><em>(<kbd>key</kbd>)</em><img class='m' /></a></li>
    */
        if ( !mo || !el ) {
            return false;
        }
        var m = mo,
            _ = this,
            li = el$('li').appendTo$(el);
        if ( p$(m,'id') ) {
            if ( !$(m.id) ) {
                li.id=m.id;
            } else {
                li.id = !$('__MENU__'+ m.id) ? '__MENU__'+ m.id : '__MENU_'+ now$(3);
            }
        } else {
            li.id='__MENU__'+ (!$('__MENU__'+ now$(3))?'':'_')+ now$(3);
        }

        if ( p$(m,'cls') ) {
            li.className = m.cls;
        }

        if ( p$(m,'css') ) {
            li.style.cssText += ((/\;$/.test(li.style.cssText)?'':';') + m.css);
        }

        if ( p$(m,'label','txt') && m.label.txt=='-|-' ) {
            li.id = '_'+ li.id;
            return li;
        }

        var a = el$('a').appendTo$(li);
        a.href = p$(m,'href') ? m.href : '#'+ li.id;
        a.id = li.id +'_A_';

        /**
         * menu item actions definition
         */
        a.onclick = typeof m.fn=='function' ?
            (function(){
                m.fn.apply(this,[]);
                _.over=false;
                return _.hide$();
            })
            : function(){return false;};

        a.onmouseover = function(){
            _.over = true;
        };
        a.onmouseout = function(){
            _.over = false;
        };

        if ( p$(m,'ico','src') ) {
            var ico = el$('img').appendTo$(a);
            ico.src = m.ico.src;
            ico.className = 'ico';
            ico.alt = m.ico.alt || '';
        }

        if ( m.label ) {
            var tx = el$('span').appendTo$(a);
            if ( p$(m,'label','id') && !$(m.label.id) ) {
                tx.id = m.label.id;
            }

            if ( p$(m,'label','cls') ) {
                tx.className = m.label.cls;
            } else {
                tx.className = 't';
            }

            if ( p$(m,'label','txt') ) {
                tx.innerHTML = m.label.txt;
            }
        }

        if ( p$(m,'key') ) {
            var em = el$('em').appendTo$(a);
            em.innerHTML = '(<kbd>'+ m.key +'<\/kbd>)';
        }

        if ( isArray(m.menu) && m.menu.length>0 ) {
            var dm = el$('img').appendTo$(a);
            dm.src = this.arr.down;
            dm.alt = '';//'▼';
            if ( p$(this,'arr','css') ) {
                dm.style.cssText = this.arr.css;
            }
            dm.className = 'm';

            /* add sub menu */
            this.sub$(m.menu,li);

            /* action for dropdown menu */
            a.onclick = function(){
                return _.togg$(li);
            };
        }
    return li;
    },

    init$: function(){
        var div = el$('div').appendTo$(this.elem);
        div.id = this.id;

        if ( this.cssname!='' ) {
            div.className = this.cssname;//for diy style
        }

        var ul = el$('ul').appendTo$(div);
        ul.className = 'mnu';
        ul.id = this.id +'_root';

        var zm = this.menu;

        if ( zm && zm.length ) {
            for ( var x=0, L=zm.length; x<L; x++ ) {
                void this.add$(zm[x],ul);
            }
        }
    return this;
    }

};